﻿using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using RotovapPlatform.Domain.Business.Machine.Enums;
using RotovapPlatform.Domain.Business.Recipes.Entities;
using RotovapPlatform.Domain.Business.Recipes.Entities.Parameters;
using static RotovapPlatform.Domain.Business.Machine.Enums.ExperimentConfigEnums;

namespace RotovapPlatform.UI.ViewModels.ExperimentManagement
{
	/// <summary>
	/// 实验视图模型，包装Experiment实体并实现属性变更通知
	/// </summary>
	public class ExperimentViewModel : INotifyPropertyChanged
	{
		private readonly Experiment _experiment;

		/// <summary>
		/// 属性变更事件
		/// </summary>
		public event PropertyChangedEventHandler PropertyChanged;

		/// <summary>
		/// 构造函数
		/// </summary>
		/// <param name="experiment">要包装的实验实体</param>
		public ExperimentViewModel(Experiment experiment)
		{
			_experiment = experiment ?? throw new ArgumentNullException(nameof(experiment));
		}

		/// <summary>
		/// 获取被包装的实验实体
		/// </summary>
		public Experiment Experiment => _experiment;

		/// <summary>
		/// 实验ID
		/// </summary>
		public Guid ExperimentId => _experiment.ExperimentId;

		/// <summary>
		/// 实验名称
		/// </summary>
		public string ExperimentName => _experiment.ExperimentName;

		/// <summary>
		/// 实验描述
		/// </summary>
		public string ExperimentDescription => _experiment.ExperimentDescription;

		/// <summary>
		/// 实验组ID
		/// </summary>
		public Guid ExperimentGroupId => _experiment.ExperimentGroupId;

		/// <summary>
		/// 实验在组内的执行顺序
		/// </summary>
		public int ExecutionOrder => _experiment.ExecutionOrder;

		/// <summary>
		/// 实验状态
		/// </summary>
		public ExperimentStatus Status
		{
			get => _experiment.Status;
			set
			{
				if (_experiment.Status != value)
				{
					_experiment.Status = value;
					OnPropertyChanged();
				}
			}
		}

		/// <summary>
		/// 当前实验阶段
		/// </summary>
		public ExperimentStage CurrentStage
		{
			get => _experiment.CurrentStage;
			set
			{
				if (_experiment.CurrentStage != value)
				{
					_experiment.CurrentStage = value;
					OnPropertyChanged();
				}
			}
		}

		/// <summary>
		/// 当前实验子阶段
		/// </summary>
		public ExperimentSubStage CurrentSubStage
		{
			get => _experiment.CurrentSubStage;
			set
			{
				if (_experiment.CurrentSubStage != value)
				{
					_experiment.CurrentSubStage = value;
					OnPropertyChanged();
				}
			}
		}

		/// <summary>
		/// 实验执行进度
		/// </summary>
		public double ExecutionProgress
		{
			get => _experiment.ExecutionProgress;
			set
			{
				if (_experiment.ExecutionProgress != value)
				{
					_experiment.ExecutionProgress = value;
					OnPropertyChanged();
				}
			}
		}

		/// <summary>
		/// 实验执行开始时间
		/// </summary>
		public DateTime? ExecutionStartTime
		{
			get => _experiment.ExecutionStartTime;
			set
			{
				if (_experiment.ExecutionStartTime != value)
				{
					_experiment.ExecutionStartTime = value;
					OnPropertyChanged();
				}
			}
		}

		/// <summary>
		/// 实验执行完成时间
		/// </summary>
		public DateTime? ExecutionEndTime
		{
			get => _experiment.ExecutionEndTime;
			set
			{
				if (_experiment.ExecutionEndTime != value)
				{
					_experiment.ExecutionEndTime = value;
					OnPropertyChanged();
				}
			}
		}

		/// <summary>
		/// 实验执行结果
		/// </summary>
		public string ExecutionResult
		{
			get => _experiment.ExecutionResult;
			set
			{
				if (_experiment.ExecutionResult != value)
				{
					_experiment.ExecutionResult = value;
					OnPropertyChanged();
				}
			}
		}

		/// <summary>
		/// 实验执行错误信息
		/// </summary>
		public string ErrorMessage
		{
			get => _experiment.ErrorMessage;
			set
			{
				if (_experiment.ErrorMessage != value)
				{
					_experiment.ErrorMessage = value;
					OnPropertyChanged();
				}
			}
		}

		/// <summary>
		/// 实验参数
		/// </summary>
		public RotovapParameters ExecutionParameters => _experiment.ExecutionParameters;

		/// <summary>
		/// 更新实验状态
		/// </summary>
		/// <param name="updatedExperiment">包含最新状态的实验实体</param>
		public void UpdateFrom(Experiment updatedExperiment)
		{
			if (updatedExperiment == null)
				return;

			// 记录原始状态
			var oldStatus = Status;
			var oldStage = CurrentStage;
			var oldSubStage = CurrentSubStage;
			var oldProgress = ExecutionProgress;

			// 更新属性
			Status = updatedExperiment.Status;
			CurrentStage = updatedExperiment.CurrentStage;
			CurrentSubStage = updatedExperiment.CurrentSubStage;
			ExecutionProgress = updatedExperiment.ExecutionProgress;

			// 通知UI所有属性可能已更改
			OnPropertyChanged(string.Empty);
		}

		/// <summary>
		/// 通知属性变更
		/// </summary>
		/// <param name="propertyName">变更的属性名称</param>
		protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
		{
			PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
		}
	}
}